<template>
    <div>
        <el-switch v-model="draggable" active-text="开启拖拽" inactive-text="关闭拖拽"></el-switch>
        <el-button v-if="draggable" @click="batchSave">批量保存</el-button>
        <el-button type="danger" @click="batchDelete">批量删除</el-button>
        <el-tree ref="menuTree" @node-drop="handleDrop" :allow-drop="allowDrop" :draggable="draggable"
            :default-expanded-keys="expandedKey" :data="menus" node-key="catId" show-checkbox
            :expand-on-click-node="false" :props="defaultProps">
            <span class="custom-tree-node" slot-scope="{ node, data }">
                <span>{{ node.label }}</span>
                <span>
                    <el-button v-if="node.level <= 2" type="text" size="mini" @click="() => append(data)">
                        Append
                    </el-button>
                    <el-button type="text" size="mini" @click="() => edit(data)">
                        Edit
                    </el-button>
                    <el-button v-if="node.childNodes.length == 0" type="text" size="mini"
                        @click="() => remove(node, data)">
                        Delete
                    </el-button>
                </span>
            </span>
        </el-tree>
        <el-dialog :close-on-click-modal="false" :title="dialogType == 'add' ? '添加分类' : '修改分类'"
            :visible.sync="dialogVisible" width="30%">
            <el-form :model="category">
                <el-form-item label="分类名称">
                    <el-input v-model="category.name" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="图标">
                    <el-input v-model="category.icon" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="计量单位">
                    <el-input v-model="category.productUnit" autocomplete="off"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitData">确 定</el-button>
            </span>
        </el-dialog>
    </div>

</template>
<script>
import Decimal from 'decimal.js'
export default {
    data() {
        return {
            draggable: false,
            pCid: [],
            updateNodes: [],
            menus: [],
            expandedKey: [],
            dialogType: '',
            maxLevel: 0,
            category: {
                name: '',
                parentCid: 0,
                catLevel: 0,
                showStatus: 1,
                sort: 0,
                catId: null,
                icon: '',
                productUnit: '',
            },
            dialogVisible: false,
            defaultProps: {
                children: 'children',
                label: 'name'
            }
        };
    },
    methods: {
        handleNodeClick(data) {
            console.log(data);
        },
        getMenus() {
            this.$http({
                url: this.$http.adornUrl('/product/category/list/tree'),
                method: 'get'
            }).then(({ data: { data: realData } }) => {
                console.log('成功获取到菜单数据--->', realData)
                this.menus = realData
            })
        },
        batchSave() {
            this.$http({
                url: this.$http.adornUrl('/product/category/update/sort'),
                method: 'post',
                data: this.$http.adornData(this.updateNodes, false)
            }).then(({ data }) => {
                this.$message({
                    message: '菜单顺序修改成功',
                    type: 'success'
                });
                this.getMenus()
                this.expandedKey = this.pCid
                this.updateNodes = []
                this.maxLevel = 0
            });
        },
        allowDrop(dragginNode, dropNode, type) { //判断节点最终能否被拖拽
            this.countNodeLevel(dragginNode)
            const deep = Math.abs(this.maxLevel - dragginNode.level) + 1
            if (type == 'inner') {
                return deep + dropNode.level <= 3
            } else {
                return deep + dropNode.parent.level <= 3
            }
        },
        handleDrop(dragginNode, dropNode, type, event) { //拖拽成功事件
            let pCid = -1
            let siblings = null
            if (type == 'before' || type == 'after') {
                pCid = dropNode.parent.data.catId == undefined ? 0 : dropNode.parent.data.catId
                siblings = dropNode.parent.childNodes
            } else {
                pCid = dropNode.data.catId
                siblings = dropNode.childNodes
            }
            for (let i = 0; i < siblings.length; i++) {
                if (siblings[i].data.catId == dragginNode.data.catId) {
                    let defaultLevel = dragginNode.level
                    if (siblings[i].level != dragginNode.data.catLevel) { //当前节点层级变化
                        defaultLevel = siblings[i].level
                        //修改其子节点层级
                        this.updateChildNodeLevel(siblings[i])
                    }
                    this.updateNodes.push({ catId: siblings[i].data.catId, sort: i, parentCid: pCid, catLevel: defaultLevel })
                } else {
                    this.updateNodes.push({ catId: siblings[i].data.catId, sort: i })
                }
            }
            this.pCid.push(pCid)
        },
        updateChildNodeLevel(node) {
            if (node.childNodes) {
                for (let i = 0; i < node.childNodes.length; i++) {
                    const cNode = node.childNodes[i].data
                    this.updateNodes.push({ catId: cNode.catId, catLevel: node.childNodes[i].level })
                    this.updateChildNodeLevel(node.childNodes[i])
                }
            }
        },
        countNodeLevel(nodeInfo) {
            if (nodeInfo.childNodes && nodeInfo.childNodes.length) {
                for (let i = 0; i < nodeInfo.childNodes.length; i++) {
                    if (nodeInfo.childNodes[i].level > this.maxLevel) {
                        this.maxLevel = nodeInfo.childNodes[i].level
                    }
                    this.countNodeLevel(nodeInfo.childNodes[i])
                }
            }
        },
        addCategory() {
            this.$http({
                url: this.$http.adornUrl('/product/category/save'),
                method: 'post',
                data: this.$http.adornData(this.category, false)
            }).then(({ data }) => {
                this.$message({
                    message: '菜单保存成功',
                    type: 'success'
                });
                this.dialogVisible = false
                this.getMenus()
                this.expandedKey = [this.category.parentCid]
            });
        },
        editCategroy() {
            const { catId, name, icon, productUnit } = this.category
            const updateObj = { catId, name, icon, productUnit }
            this.$http({
                url: this.$http.adornUrl('/product/category/update'),
                method: 'post',
                data: this.$http.adornData(updateObj, false)
            }).then(({ data }) => {
                this.$message({
                    message: '菜单修改成功',
                    type: 'success'
                });
                this.dialogVisible = false
                this.getMenus()
                this.expandedKey = [this.category.parentCid]
            });
        },
        submitData() {
            if (this.dialogType == "add") {
                this.addCategory()
            }
            if (this.dialogType == "edit") {
                this.editCategroy()
            }
        },
        edit(data) {
            //快速整理代码alt+shift+f
            this.dialogType = "edit"
            this.dialogVisible = true
            this.$http({
                url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
                method: 'get',
                params: this.$http.adornParams({})
            }).then(({ data }) => {
                this.category.name = data.data.name
                this.category.catId = data.data.catId
                this.category.icon = data.data.icon
                this.category.productUnit = data.data.productUnit
                this.category.parentCid = data.data.parentCid
            });
        },
        append(data) {
            this.dialogType = "add"
            this.dialogVisible = true
            this.category.parentCid = data.catId
            this.category.catLevel = +data.catLevel + 1
            console.log(this.category)
            this.category.name = ''
            this.category.catId = null
            this.category.icon = ''
            this.category.productUnit = ''
        },
        /*
         Vscode配置代码片段:文件-首选项-配置代码片段-vue.json.code-snippets
        */
        remove(node, data) {
            this.$confirm(`是否删除【${data.name}】菜单？`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                const ids = [data.catId]
                this.$http({
                    url: this.$http.adornUrl('/product/category/delete'),
                    method: 'post',
                    data: this.$http.adornData(ids, false)
                }).then(res => {
                    this.getMenus()
                    this.expandedKey = [node.parent.data.catId]
                    this.$message({
                        message: '菜单删除成功',
                        type: 'success'
                    });
                })
            }).catch(() => {

            });
        },
        batchDelete() {
            const checkNodeList = this.$refs.menuTree.getCheckedNodes()
            console.log('选中的节点', checkNodeList)
            const checkIdList = checkNodeList.map(item => item.catId)
            this.$confirm(`是否批量删除【${checkIdList.join(',')}】菜单？`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$http({
                    url: this.$http.adornUrl('/product/category/delete'),
                    method: 'post',
                    data: this.$http.adornData(checkIdList, false)
                }).then(({ data }) => {
                    this.$message({
                        message: '菜单批量删除成功',
                        type: 'success'
                    });
                    this.getMenus()
                });
            }).catch(() => { })
        }
    },
    created() {
        this.getMenus()
    },

}
</script>